<?php

  /**
   *
   */
class Cicp
{
    private $_graphManager    = null;             
    private $_storageDriver   = null;             
    private $_outputProcessor = null;             
    private $_inputProcessor  = null;       
    private $_userHandler     = null;

    static private $_instance = null; // singleton

    /**
     * initiates instances of subclasses like GraphManager and
     * OutputProcessor sets singleton of class to this instance
     */
    function __construct()
    {
        $this->_graphManager = new Cicp_GraphManager();
        $this->_outputProcessor = new Cicp_OutputProcessor();
        $this->_inputProcessor = new Cicp_InputProcessor();
        $this->_storageDriver = new Cicp_StorageDriver_NullDriver();
        $this->_userHandler = new Cicp_Handler_NullHandler();

        self::setInstance($this);
    }

    function processInput($cicpLine)
    {
        Cicp::getInstance()->getInputProcessor()->processCicpLine($cicpLine);
    }
    
    /*** Getters/Setters ***/

    /**
     * returns instance of Cicp or creates a new one
     */
    static function getInstance()
    {
        if (self::$_instance instanceof Cicp) {
            return self::$_instance;
        }
        else {
            return new Cicp;
        }
    }

    /**
     * sets $cicpObject as single instance of Cicp
     */
    static function setInstance(Cicp $cicpObject)
    {
        try {
            if (self::$_instance instanceof Cicp) {
                throw new Cicp_Exception_InstanceActive('Instance of Cicp already active.');
            }
            else {
                self::$_instance = $cicpObject;
                return $cicpObject;
            }
        }
        catch (Cicp_Exception_InstanceActive $e) {
            return self::getInstance();
        }
        catch (Exception $e) {
            throw $e;
        }
    }

    /**
     * returns input processor
     */
    function getInputProcessor()
    {
        return $this->_inputProcessor;
    }

    function getOutput()
    {
        return Cicp::getInstance()->getOutputProcessor()->getOutput();
    }

    /**
     * returns output processor
     */
    function getOutputProcessor()
    {
        return $this->_outputProcessor;
    }

    /** 
     * returns storage driver
     */
    function getStorageDriver()
    {
        return $this->_storageDriver;
    }

    /**
     * sets storage driver for this instance
     */
    function setStorageDriver(Cicp_StorageDriver_Interface $driver)
    {
        $this->_storageDriver = $driver;
    }

    /**
     * sets user handler for this instance to $handler
     */
    function setUserHandler(Cicp_Handler_Interface $handler)
    {
        $this->_userHandler = $handler;
    }

    /**
     * return user handler
     */
    function getUserHandler()
    {
        return $this->_userHandler;
    }

    /**
     * returns graph manager
     */
    function getGraphManager()
    {
        return $this->_graphManager;
    }

    /**
     * returns last error message
     */
    function getErrorMessage()
    {
        return $this->_errorMessage;
    }

    /**
     * stores an error
     */
    function error($errorMessage)
    {
        $this->_errorMessage = $errorMessage;
    }
}